package com.yc.qunxing.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yc.qunxing.entity.Drivers;
import com.yc.qunxing.entity.Orders;
import com.yc.qunxing.entity.Users;
import com.yc.qunxing.entity.vo.OrderDetails;
import com.yc.qunxing.entity.vo.OrderDetailsDriver;
import com.yc.qunxing.entity.vo.RouteFrequency;
import com.yc.qunxing.mapper.DriversMapper;
import com.yc.qunxing.mapper.OrdersMapper;
import com.yc.qunxing.mapper.UsersMapper;
import com.yc.qunxing.service.IOrdersService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 鹏哥
 * @since 2024-05-23
 */
@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements IOrdersService {

    @Autowired
    public  OrdersMapper ordersMapper;
    @Autowired
    private DriversMapper driversMapper;
    @Autowired
    private UsersMapper usersMapper;
    @Override
    public Integer addOrder(Orders orders) {
        ordersMapper.insertAndGetId(orders);
        System.out.println(orders.getOrderId());
        return orders.getOrderId();
    }

    @Override
    public List<RouteFrequency> getRouteFrequenciesByUserId(Integer userId) {
        return ordersMapper.getRouteFrequenciesByUserId(userId);
    }
    public List<OrderDetails> getOrdersAndDriverInfo(Integer userId) {
        List<Orders> orders = ordersMapper.getOrdersByUserId(userId);
        Map<Integer, Drivers> driversMap = new HashMap<>();

        // 查找所有不同的 driverId
        for (Orders order : orders) {
            Integer driverId = order.getDriverId();
            if (driverId != null && !driversMap.containsKey(driverId)) {
                Drivers driver = driversMapper.getDriverDetailsById(driverId);
                if (driver != null) {
                    driversMap.put(driverId, driver);
                }
            }
        }

        List<OrderDetails> orderDetailsList = new ArrayList<>();
        for (Orders order : orders) {
            OrderDetails details = new OrderDetails();
            details.setOrderNumber(order.getOrderId().toString());
            details.setStatus(order.getStatus());

            Drivers driver = driversMap.get(order.getDriverId());
            if (driver != null) {
                details.setDriverName(driver.getUsername());
                details.setLicensePlate(driver.getLicensePlate());
                details.setPhoneNumber(driver.getPhoneNumber());
                if (driver.getDriverVehicles() != null) {
                    details.setVehicleType(driver.getDriverVehicles().getVehicleType());
                    details.setColor(driver.getDriverVehicles().getColor());
                }
            }

            orderDetailsList.add(details);
        }

        return orderDetailsList;
    }

    @Override
    public List<OrderDetailsDriver> getOrdersAndUserInfo(Integer driverId) {
        List<Orders> orders = ordersMapper.getOrdersByDriverId(driverId);
        Map<Integer, Users> usersMap = new HashMap<>();

        // 查找所有不同的 userId
        for (Orders order : orders) {
            Integer userId = order.getUserId();
            if (userId != null && !usersMap.containsKey(userId)) {
                Users user= usersMapper.getUserDetailsById(userId);
                if (user != null) {
                    usersMap.put(userId, user);
                }
            }
        }
        List<OrderDetailsDriver> orderDetailsDriverList = new ArrayList<>();
        for (Orders order : orders) {
            OrderDetailsDriver details = new OrderDetailsDriver();
            details.setOrderNumber(order.getOrderId().toString());
            details.setStatus(order.getStatus());

            Users user = usersMap.get(order.getUserId());
            if (user != null) {
                details.setPhoneNumber(user.getPhoneNumber());
                details.setUserName(user.getUsername());
            }

            orderDetailsDriverList.add(details);
        }

        return orderDetailsDriverList;
    }

    @Override
    public List<Orders> getOrderDetailsByUserId(Integer userId) {
        return ordersMapper.getOrderDetailsByUserId(userId);
    }

    @Override
    public List<Orders> getOrderDetailsByDriverId(Integer driverId) {
        return ordersMapper.getOrderDetailsByDriverId(driverId);
    }

    @Override
    public int countOrdersWithStatus5(Integer userId) {
        return ordersMapper.countOrdersWithStatus5(userId);
    }

    @Override
    public List<Orders> getOrdersByUserId(Integer userId, String keyword,String keywordOrder) {
        QueryWrapper<Orders> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        if (keyword != null && !keyword.isEmpty()) {
            queryWrapper.and(wrapper -> wrapper
                    .like("order_id", keyword)
                    .or()
                    .like("driver_id", keyword)
                    .or()
                    .like("departure_location", keyword)
                    .or()
                    .like("destination_location", keyword)
                    .or()
                    .like("actual_amount", keyword));
        }
        if (keywordOrder != null && !keywordOrder.isEmpty()) {
            queryWrapper.like("status", keywordOrder);
        }
        queryWrapper.orderByDesc("order_date");
        return ordersMapper.selectList(queryWrapper);
    }
    @Override
    public List<Orders> getOrdersByDriverId(Integer driverId, String keyword,String keywordOrder) {
        QueryWrapper<Orders> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("driver_id", driverId);
        if (keyword != null && !keyword.isEmpty()) {
            queryWrapper.and(wrapper -> wrapper
                    .like("order_id", keyword)
                    .or()
                    .like("user_id", keyword)
                    .or()
                    .like("departure_location", keyword)
                    .or()
                    .like("destination_location", keyword)
                    .or()
                    .like("total_amount", keyword));
        }
        if (keywordOrder != null && !keywordOrder.isEmpty()) {
            queryWrapper.like("status", keywordOrder);
        }
        queryWrapper.orderByDesc("order_date");
        return ordersMapper.selectList(queryWrapper);
    }

    @Override
    public List<Orders> getOrdersByManager(String keyword,String keywordOrder) {
        QueryWrapper<Orders> queryWrapper = new QueryWrapper<>();
        if (keyword != null && !keyword.isEmpty()) {
            queryWrapper.and(wrapper -> wrapper
                    .like("order_id", keyword)
                    .or()
                    .like("driver_id", keyword)
                    .or()
                    .like("user_id", keyword)
                    .or()
                    .like("departure_location", keyword)
                    .or()
                    .like("destination_location", keyword)
                    .or()
                    .like("total_amount", keyword)
                    .or()
                    .like("actual_amount", keyword));
        }
        if (keywordOrder != null && !keywordOrder.isEmpty()) {
            queryWrapper.like("status", keywordOrder);
        }
        queryWrapper.orderByDesc("order_date");
        return ordersMapper.selectList(queryWrapper);
    }

    public Map<String, Object> getOrderStatistics() {
        Map<String, Object> result = new HashMap<>();

        // 订单数量统计
        List<Map<String, Object>> orderCounts = ordersMapper.getOrderCountPerMonth();
        result.put("orderCounts", orderCounts);

        // 车辆类型统计
        List<Map<String, Object>> vehicleTypeCounts = ordersMapper.getVehicleTypeCountPerMonth();
        result.put("vehicleTypeCounts", vehicleTypeCounts);

        // 车辆颜色统计
        List<Map<String, Object>> colorCounts = ordersMapper.getColorCountPerMonth();
        result.put("colorCounts", colorCounts);

        return result;
    }

    public List<Map<String, Object>> getRanking(String timeRange) {
        QueryWrapper<Orders> queryWrapper = new QueryWrapper<>();
        LocalDateTime startDateTime;

        switch (timeRange) {
            case "today":
                startDateTime = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0).withNano(0);
                break;
            case "month":
                startDateTime = LocalDateTime.now().withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
                break;
            case "year":
                startDateTime = LocalDateTime.now().withDayOfYear(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
                break;
            default:
                throw new IllegalArgumentException("Invalid time range");
        }

        queryWrapper.ge("order_date", startDateTime)
                .in("status", 2, 3);

        List<Orders> ordersList = this.list(queryWrapper);

        Map<Integer, List<Orders>> ordersByDriver = ordersList.stream()
                .collect(Collectors.groupingBy(Orders::getDriverId));

        List<Map<String, Object>> ratingRanking = ordersByDriver.entrySet().stream()
                .map(entry -> {
                    Integer driverId = entry.getKey();
                    List<Orders> driverOrders = entry.getValue();
                    Double averageRating = driverOrders.stream()
                            .mapToInt(Orders::getRateValue)
                            .average()
                            .orElse(0.0);
                    return Map.of("driverId", driverId, "averageRating", (Object) averageRating);
                })
                .sorted((a, b) -> Double.compare((Double) b.get("averageRating"), (Double) a.get("averageRating")))
                .limit(3)
                .collect(Collectors.toList());

        List<Map<String, Object>> revenueRanking = ordersByDriver.entrySet().stream()
                .map(entry -> {
                    Integer driverId = entry.getKey();
                    List<Orders> driverOrders = entry.getValue();
                    BigDecimal totalRevenue = driverOrders.stream()
                            .map(Orders::getTotalAmount)
                            .reduce(BigDecimal.ZERO, BigDecimal::add);
                    return Map.of("driverId", driverId, "totalRevenue", (Object) totalRevenue);
                })
                .sorted((a, b) -> ((BigDecimal) b.get("totalRevenue")).compareTo((BigDecimal) a.get("totalRevenue")))
                .limit(3)
                .collect(Collectors.toList());

        List<Map<String, Object>> ordersRanking = ordersByDriver.entrySet().stream()
                .map(entry -> {
                    Integer driverId = entry.getKey();
                    Long orderCount = (long) entry.getValue().size();
                    return Map.of("driverId", driverId, "orderCount", (Object) orderCount);
                })
                .sorted((a, b) -> Long.compare((Long) b.get("orderCount"), (Long) a.get("orderCount")))
                .limit(3)
                .collect(Collectors.toList());

        return List.of(
                Map.of("type", (Object) "rating", "ranking", (Object) ratingRanking),
                Map.of("type", (Object) "revenue", "ranking", (Object) revenueRanking),
                Map.of("type", (Object) "orders", "ranking", (Object) ordersRanking)
        );
    }
}

